#include <timberyard/exception.h>
#include <cstring>
#include <cerrno>
#include <iostream>

namespace Timberyard {

Exception::Exception() : m_stack(1), m_text(), m_tags() {
	char buf[256];
	bzero(buf,256);
	// gnu strerror isn't quite posix.
	// TODO: make portable.
	char* problem=strerror_r(errno,buf,256);
	m_text=problem;
}

Exception::Exception(int i) : m_stack(1), m_text(),m_tags() {
	char buf[256];
	bzero(buf,256);
	// gnu strerror isn't quite posix.
	// TODO: make portable.
	char* problem=strerror_r(i,buf,256);
	m_text=problem;
}

const char* Exception::what() const throw() try {
  std::string s=m_text;
  for (std::list<ThrowTag>::const_iterator i=m_tags.begin(); i!=m_tags.end(); ++i) {
		s+=i->Display();
	}
//		"\nThread: "+(t==0?std::string("init"):t->ThreadName())+
	s+="\nStack:\n"+m_stack.AsString();
  return s.c_str();
} catch(...) {
  return "Exception is corrupt";
}

std::string ThrowTag::Display() const {
	return m_name+": "+m_value+"\n";
}

Exception& Exception::operator<<(const ThrowTag& t) {
	m_tags.push_back(t);
	return *this;
}


} // namespace Timberyard
